import qrcode
import requests
import json
import urllib.request
from base.base_config import *
from common import check
from common.devices_sign import regist_sign, login_sign
from datetime import datetime
from functools import wraps


"""
归纳常用方法
"""


def katou_login(mac_id, paydevicetype, shownum):
    ts = int(time.time() * 1000)  # time.time()以秒为单位，要乘以1000进位至毫秒
    sign = regist_sign(paydevicetype=paydevicetype, ts=ts, macid=mac_id, shownum=shownum)

    url = BASE_URL + '/Hardware/api/v1.0/Pay/PreRegist'
    header = {
        "Content-Type": "application/json",
        "Accept-Charset": "utf-8",
        "Sign": sign
    }
    regist_data = {
        "MacID": mac_id,
        "Sign": sign,
        "TS": ts,
        "PayDeviceType": paydevicetype,
        "ShowNum": int(shownum),
    }

    session = requests.session()
    regist_response = session.post(url=url, json=regist_data, headers=header)
    check.check_response_status(regist_response)

    # if regist_response.json()["Data"]["IsReg"] == 'true':
    appid = regist_response.json()["Data"]["AppID"]
    key = regist_response.json()["Data"]["Key"]

    data = {
        "AppID": appid,
        "MacID": mac_id,
        "Sign": key,
        "AppVer": 202,
        "HardVer": 202,
        "TS": ts,
        "TerminalType": 1
    }

    header = {
        "Content-Type": "application/json",
        "Accept-Charset": "utf-8",
        "Authorization": key
    }

    url = BASE_URL + '/Hardware/api/v1.0/Public/LoginToken'
    token_res = session.post(url=url, json=data, headers=header)
    check.check_response_status(token_res)

    url = BASE_URL + '/Hardware/api/v1.0/Pay/GetConfig'

    # get_config_res = session.post(url=url, headers=header)
    # check.check_response_status(get_config_res)


# 通用登录接口,支持各自助设备
def login_for_devices(terminal_type, mac_id, app_ver=20191028):
    """
    :param terminal_type: 设备类型
    :param mac_id: 设备唯一标识
    :param app_ver: 程序版本
    :return: token_header: 带token的请求头
    """
    ts = int(time.time() * 1000)  # time.time()以秒为单位，要乘以1000进位至毫秒
    sign = regist_sign(terminaltype=terminal_type, ts=ts, macid=mac_id)

    # 注册验签
    header = {
        "Content-Type": "application/json",
        "Accept-Charset": "utf-8",
        "Authorization": sign
    }
    regist_data = {
        "MacID": mac_id,
        "Sign": sign,
        "TS": ts,
        "TerminalType": terminal_type,
    }
    RegistDevToken_Url = BASE_URL + "/Hardware/api/v1.0/Public/RegistDevToken"
    session = requests.session()
    regist_response = session.post(url=RegistDevToken_Url, json=regist_data, headers=header)
    check.check_response_status(regist_response)

    appid = regist_response.json()['Data']['AppID']
    appkey = regist_response.json()['Data']['AppKey']

    # 连接测试
    connectTest_url = BASE_URL + "/Hardware/api/v1.0/Public/ConnectTest"
    connectTest_response = session.get(url=connectTest_url, headers=BASE_HEADER)
    check.check_response_status(connectTest_response)

    # 登录
    loginsign = login_sign(terminaltype=3, macid=mac_id, ts=ts, appid=appid, appkey=appkey, appver=app_ver)  # 获取登录验签

    login_url = BASE_URL + "/Hardware/api/v1.0/Public/LoginToken"
    login_data = {
        "AppID": appid,
        "AppVer": app_ver,
        "MacID": mac_id,
        "Sign": loginsign,
        "TS": ts,
        "TerminalType": terminal_type
    }

    login_response = session.post(url=login_url, json=login_data, headers=BASE_HEADER)
    check.check_response_status(login_response)

    Token = login_response.json()['Data']['Token']

    # 获取基本配置信息
    baseinfo_setting_url = BASE_URL + "/Hardware/api/v1.0/TakeCard/GetBaseSetting"
    token_header = {
        "Content-Type": "application/json",
        "Accept-Charset": "utf-8",
        "Authorization": Token
    }
    baseinfo_response = session.post(url=baseinfo_setting_url, headers=token_header)
    check.check_response_status(baseinfo_response)
    return token_header


# 通用登录接口,支持大客户门店后台
def login_for_background_md():
    login_url = BASE_URL + "/DTOLogin"
    data = {
        "UserName": loc['数据']['用户名'],
        "Password": loc['数据']['密码'],
        "TerminalID": "7BD1C44E-F5F4-4D24-8C79-A4C000F9F886"  # 后台系统的TerminalID，所有数据库通用
    }
    session = requests.session()
    response = session.post(url=login_url, json=data, headers=BASE_HEADER)
    check.check_response_status(response)
    return session


# 通用登录接口,支持大客户总部后台
def login_for_background_zb():
    login_url = BASE_URL_ZB + "/DTOLogin"
    data = {
        "UserName": loc['User_Data']['user'],
        "Password": loc['User_Data']['pwd'],
        "TerminalID": "7BD1C44E-F5F4-4D24-8C79-A4C000F9F886"  # 后台系统的TerminalID，所有数据库通用
    }
    session = requests.session()
    response = session.post(url=login_url, json=data, headers=BASE_HEADER)
    check.check_response_status(response)
    return session


# 规律新增商品名称,YLB,DKH通用
def regular_good_name(goodname):
    """
    :param goodname: 商品名称
    :return: _name: 递增的名称
    """
    """从数据库获取最新编码的商品名称"""
    sql = "select TOP (1) GoodName from Mall_GoodBase where GoodName like '"+goodname+"____' and Isdelete=0 order by GoodName desc"
    getgoodname = DB_MD.ExecQuery(sql)
    '''判断是否有初始001的商品名称，如果没有赋予一个000的name，如果有，则直接拿取'''
    if not getgoodname:
        name = '000'
    else:
        name = getgoodname[0][0]
    '''拿取商品名后3位的编号，判断是否编号是否大于等于001，如果是则编号加1，如果不是则设置初始值为：1'''
    if name[-3:] >= '001':
        number = int(name[-3:]) + 1
    else:
        number = 1
    '''将最新的编号赋予'''
    _name = goodname + "_" + str(number).zfill(3)  # zfill函数自动以0补位
    # print('当前最新:{}'.format(_name))
    return _name


# 规律各类型名称
def regular_many_kind_of_name(names, database="MD", namekind=None):
    """
    递增各业务类型数据名称
    :param names: 业务名称
    :param database: 数据库类型: MD:门店  ZB:总部
    :param namekind: 业务类型, 自定义: 共用角色、商品分类、会员级别、仓库、收银终端
    :return: _name: 递增业务名称
    """
    global sql, getgoodname
    if namekind == '共用角色':
        sql = "select TOP (1) LevelName from Mall_EmployeeLevel where LevelName like '" + names + "____' and Isdelete=0 order by LevelName desc"
    elif namekind == '商品分类':
        sql = "select TOP (1) ClassName from Mall_GoodClass where ClassName like '" + names + "____' and Isdelete=0 order by ClassName desc"
    elif namekind == '会员级别':
        sql = "select TOP (1) LevelName from Mall_LeaguerLevel where LevelName like '" + names + "____' and Isdelete=0 order by LevelName desc"
    elif namekind == '仓库':
        sql = "select TOP (1) Name from Mall_Stock where Name like '" + names + "____' and Isdelete=0 order by Name desc"
    elif namekind == '收银终端':
        sql = "select TOP (1) TerminalName from Mall_Terminal where TerminalName like '" + names + "____' and Isdelete=0 order by TerminalName desc"
    else:
        print("\033[0;96;0m请输入对应新增数据类型: \n1.共用角色 \n2.商品分类 \n3.会员级别 \n4.仓库 \n5.收银终端\033[0m")

    if database == 'MD':
        getgoodname = DB_MD.ExecQuery(sql)
    elif database == 'ZB':
        getgoodname = DB_ZB.ExecQuery(sql)

    if not getgoodname:
        name = '000'
    else:
        name = getgoodname[0][0]

    if name[-3:] >= '001':
        number = int(name[-3:]) + 1
    else:
        number = 1
    '''将最新的编号赋予'''
    _name = names + "_" + str(number).zfill(3)  # zfill函数自动以0补位
    # print('当前最新:{}'.format(_name))
    return _name


# 规律新增ICNum,PrintNum, YLB,DKH通用
def regular_cardNum():
    """从数据库获取最新编码的商品名称"""
    global card_num, print_num
    sql = "select TOP 1 ICNumber,PrintNumber from Mall_ICCard where ICNumber like 'lqr_cjz____' and IsDelete=0 and IsEnable=1 order by ICNumber desc"
    getNum = DB_MD.ExecQuery(sql)

    if not getNum:
        card_num = '0000'
        print_num = '0000'
    else:
        print(getNum[0][0][-4:], getNum[0][1][-6:])
        card_num, print_num = getNum[0][0][-4:], getNum[0][1][-6:]

    if card_num >= '0001':
        card_num = int(card_num) + 1
    else:
        card_num = 1

    if print_num >= '000001':
        print_num = int(print_num) + 1
    else:
        print_num = 1

    '''将最新的编号赋予'''
    business_num = DB_MD.ExecQuery('select BusinessNum from Mall_Business where BusinessType=4')[0][0]
    ICNum = 'lqr_cjz' + str(card_num).zfill(4)  # zfill函数自动以0补位
    PrintNum = business_num + datetime.now().strftime("%Y") + str(print_num).zfill(6)
    return ICNum, PrintNum


# 转换图片为base64
def convert_photo_to_base64(PhotoPath):
    f = open(PhotoPath, 'rb')  # 二进制方式打开图文件
    ls_f = base64.b64encode(f.read())  # 读取文件内容，转换为base64编码
    f.close()
    bs64 = ls_f.decode()
    return bs64


# 发送内容至对应请求,如发送内容至钉钉机器人
def send_request(url, datas):
    #  构建请求头部
    header = {
    "Content-Type": "application/json",
    "Charset": "UTF-8"
    }
    sendData = json.dumps(datas)  # 将字典类型数据转化为json格式
    sendDatas = sendData.encode("utf-8")  # python3的Request要求data为byte类型
    #  发送请求
    request = urllib.request.Request(url=url, data=sendDatas, headers=header)
    #  将请求发回的数据构建成为文件格式
    opener = urllib.request.urlopen(request)
    #  打印返回的结果
    # print(opener.read())


# 发送文件至钉钉
def send_file_to_dingding():
    access_token = '1554a3dd1e748cbf748e8e0ea9d3cb61c2ee008d32167313389ff14cccda34a2'
    path = r'E:\PyProject\Hardware_Devices_Interface\test_report\report\2020-03-31 17-14-19_TestResult_Report.html'  # 文件路径
    url = 'https://oapi.dingtalk.com/media/upload?access_token=' + access_token + '&type=file'
    files = {'media': open(path, 'rb')}
    data = {'access_token': access_token,
            'type': 'file'}
    response = requests.post(url, files=files, data=data)
    media_id = response.json()

    media_id = media_id
    chatid = '*******'  # 通过jsapi工具获取的群聊id
    url = 'https://oapi.dingtalk.com/chat/send?access_token=' + access_token
    header = {
        'Content-Type': 'application/json'
    }
    data = {'access_token': access_token,
            'chatid': chatid,
            'msg': {
                'msgtype': 'file',
                'file': {'media_id': media_id}
            }}
    r = requests.request('POST', url, data=json.dumps(data), headers=header)
    print(r.json())


# 记录执行时间
def func_time(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = f(*args, **kwargs)
        end = time.time()
        print(f.__name__, 'took', end - start, 'seconds')
        return result
    return wrapper

# 生成二维码图片
@func_time
def make_qr(info, save):
    qr = qrcode.QRCode(
        version=4,  # 生成二维码尺寸的大小 1-40  1:21*21（21+(n-1)*4）
        error_correction=qrcode.constants.ERROR_CORRECT_M,  # L:7% M:15% Q:25% H:30%
        box_size=4,  # 每个格子的像素大小
        border=4,  # 边框的格子宽度大小
    )
    qr.add_data(info)
    qr.make(fit=True)
    img = qr.make_image()
    img.save(save)
    return img

my_data = {
            "msgtype": "markdown",
            "markdown": {"title": "测试",
                         "text": " aoaooaoqw"},
            "at": {"isAtAll": True}
            }

if __name__ == '__main__':
    # login_for_devices(DKH_BG)
    # regular_cardNum()
    # send_request(get_dingding_api(), my_data)
    katou_login(mac_id='004CBE0E0016301C', paydevicetype=2, shownum=164800)
    # regular_good_name("test")
    # send_file_to_dingding()
